﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using LowLevelGraphics.Types.Interval;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Multi Threshold Mode
    /// </summary>
    public enum MULTITHRESHOLD_MODE
    {
        FOREGROUND_COLOR,
        BACKGROUND_COLOR,
        FOREGROUND_MASK,
        BACKGROUND_MASK
    }

    /// <summary>
    /// Multi Threshold
    /// </summary>
    public class MultiThreshold : BaseForeBackgroundColorFilter
    {
        protected FloatInterval[] m_aFloatIntervall = null;
        protected MULTITHRESHOLD_MODE m_MODE = MULTITHRESHOLD_MODE.BACKGROUND_MASK;
        protected bool m_bInvertResult = false;

        protected PerPixelFilter.PerPixelFilterDelegate m_PerPixelFilterDelegate = new PerPixelFilter.PerPixelFilterDelegate(delegate(Color _color) { return _color; });
        
        /// <summary>
        /// Default Constructor
        /// </summary>
        public MultiThreshold()
        {
            M_PROCESSING_MODE = PROCESSING_MODE.GrayValue;
            m_aFloatIntervall = new FloatInterval[] { 
                new FloatInterval(0, 50), 
                new FloatInterval(127, 200), 
                new FloatInterval(70, 90)
            };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_multiThreshold"></param>
        internal MultiThreshold(MultiThreshold _multiThreshold)
        {
            m_aFloatIntervall = _multiThreshold.m_aFloatIntervall;
            m_MODE = _multiThreshold.m_MODE;
            m_bInvertResult = _multiThreshold.m_bInvertResult;
        }

        /// <summary>
        /// Gets or sets float Intervall
        /// </summary>
        public FloatInterval[] FloatIntervall
        {
            get { return m_aFloatIntervall; }
            set { m_aFloatIntervall = value; }
        }

        /// <summary>
        /// Invert Result
        /// </summary>
        public bool InvertResult
        {
            get { return m_bInvertResult; }
            set { m_bInvertResult = value; }
        }

        /// <summary>
        /// Gets or sets mode...
        /// </summary>
        public MULTITHRESHOLD_MODE MODE
        {
            get { return m_MODE; }
            set { m_MODE = value; }
        }

        /// <summary>
        /// Executes this filter...
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            int nWidth = _bitmap.Width;
            int nHeight = _bitmap.Height;
            int y = 0;
            int x = 0;

            ColorCalculation colorCalculation = Definitions.ColorCalculationDictionaryProcessingMode[M_PROCESSING_MODE];

            Color color = Color.Transparent;
            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    color = _bitmap.GetPixel(x, y);
                    float fResult = colorCalculation(color);

                    bool bContained = false;
                    foreach (FloatInterval interVall in m_aFloatIntervall)
                    {
                        bContained |= interVall.Contains(fResult);
                    }
                    if (m_bInvertResult) bContained = !bContained;
                    switch (m_MODE)
                    {
                        case MULTITHRESHOLD_MODE.FOREGROUND_COLOR:
                            color = bContained ? m_ColorForeground : m_ColorBackground;
                            break;

                        case MULTITHRESHOLD_MODE.BACKGROUND_COLOR:
                            color = bContained ? m_ColorBackground : m_ColorForeground;
                            break;

                        case MULTITHRESHOLD_MODE.FOREGROUND_MASK:
                            color = bContained ? color : m_ColorBackground;
                            break;

                        case MULTITHRESHOLD_MODE.BACKGROUND_MASK:
                            color = bContained ? m_ColorForeground : color;
                            break;

                        default:
                            break;
                    }
                    _bitmap.SetPixel(x, y, m_PerPixelFilterDelegate(color));
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// Clones this instance
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new MultiThreshold(this);
        }
    }
}
